Hi Dai Gei Ho~ 我是Winnie ~ 同樣地延續Service Worker的主題(是SW系列的最後一篇了),今天我們要來實作 service worker 另一個常見功能 訂閱推播,帶大家了解下其中的運作原理。
訂閱推播 是什麼?
簡單來說就是 使用者在訂閱相關網站後,網站可以透過需求傳遞通知訊息給已訂閱的使用者。
而在 訂閱推播 功能中,主要可以分為 推送(Push) 與 通知(notification)
首先,開始在 Browser 中註冊一個 Service Worker,且回傳一個Promise,如果成功的話就會回傳一個ServiceWorkerRegistration
參數,接著透過 pushManager
方法來調用 getSubscription
判斷是否已經訂閱。
範例中回傳參數 swReg 即為 ServiceWorkerRegistration
if ('serviceWorker' in navigator && 'PushManager' in window) {
// sw register
navigator.serviceWorker.register('/sw.js', {
scope: '/'
})
.then((swReg) => {
swReg.pushManager.getSubscription().then(subscription => {
// 使用者沒有訂閱
if (!subscription) {
subscribeUser(swReg);
} else {
console.log("You have subscribed our notification");
}
});
})
} else {
console.log('Push message is not Supported');
}
如果未訂閱,此時會觸發.pushManager.subscribe
方法來向使用者發起訂閱通知的權限,同時此方法也會回傳一個Promise。
其中在pushManager.subscribe
中的兩個參數,分別為:
userVisibleOnly : 表示每次收到推送時顯示通知,通常設置為 true。
applicationServerKey : 為 server 端所提供的公鑰,主要用來生成 subscription 資訊,而在server端 的 私鑰 主要功用為Push
const subscribeUser= (swReg)=>{
const applicationServerKey = urlB64ToUint8Array(publicVapidKey);
swReg.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey
})
.then(subscription =>{
// 訂閱成功
updateSubscription(subscription)
})
.catch((err)=>{
console.log('訂閱失敗: ', err);
});
}
const updateSubscription = (subscription) => {
console.log(subscription);
fetch('/subscribe', {
method: 'POST',
body: JSON.stringify(subscription),
headers: {
"content-type": 'application/json'
}
}).catch((err) => { console.log(err); })
}
此時server端會接收到 subscription
的內容,大概像下方這樣
{
endpoint: '.....',
keys: {
auth: '.....',
p256dh: '.....'
}
};
server端接收到 subscription 資訊後,就可以推播訊息給使用者
這邊 我們 用node.js來模擬server端可能運行的方式,如有不全的地方請見諒
app.post('/subscribe', (req, res)=> {
//取得 subscription 資訊
const subscription = req.body;
res.status(200).json({});
//推播內容
const payload = JSON.stringify({ title: "大俠愛吃漢堡飽" });
// push 給推播內容
webpush
.sendNotification(subscription, payload)
.catch(err => console.error('rrrrrrrr:'))
})
最後,當server端推播訊息到Browser端時,背後運行的 Service Worker 會觸發 Push 事件,此時可以透過 registration.showNotification
來顯示通知。
self.addEventListener("push", e => {
console.log('notification is success!!');
const data = e.data.json();
event.waitUntil(
self.registration.showNotification(data.title, {
body: "訂閱成功!",
icon: "http://pic.616pic.com/ys_b_img/00/44/76/JNaUexjx51.jpg",
data: {
dateOfArrival: Date.now(),
primaryKey: 1
}
});
);
});
咦? 那可以做到 點擊通知訊息導向到指定頁面嗎?
可以的,可以透過notificationclick'
來監聽被點擊事件,clients.openWindow
為新增一個頁面。
self.addEventListener('notificationclick', e=> {
const notification = e.notification;
const primaryKey = notification.data.primaryKey;
const action = e.action;
if (action === 'close') {
//點擊關閉則關閉
notification.close();
} else {
//點擊其他地方打開指定連結 clients.openWindow(url);
notification.close();
}
});
到這裡就完成一個Service Worker的 訂閱推播了(呼 壓線了
以上就是關於 Service Worker 常見功能 訂閱推播 實作介紹(呼,而在下一篇文章將回歸原本的主題 Chrome Extension 接下去後續的介紹。
那今天文章先到這邊了,謝謝願意花時間看此篇文章的你,如果文章有錯誤的地方,再麻煩不吝嗇的給予指教,感謝!!
今日有感而發:
記得去年這時候,第一次參加鐵人賽,每天都好焦慮
害怕錯誤、擔心敘述、操心沒必要的操心 ,而今年,我還是一樣,只是擔心的東西不同了
因為我擔心我的梗圖無法在對的地方登場,你說奇怪不奇怪,原來 我又進步了
今天想分享一首 -> 思念是一種病